package com.g2room.driving.grap.life;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.jsoup.HttpStatusException;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.fastjson.JSON;
import com.g2room.driving.grap.GenericGrap;
import com.g2room.driving.grap.life.model.po.ComShop;
import com.g2room.driving.grap.life.model.po.ComShopImgs;
import com.g2room.myuall.grap.ky.model.po.GrapErr;
import com.g2room.myuall.util.DbUtil;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
/**
 * 大众点评评价信息
 * @author butterfly
 *
 */
public class GrabDzdpImgsDataByProxy implements Runnable {
	public static String baseUrl = "http://www.dianping.com/shop/#id#/";
	private String source = "大众点评";
	@Override
	public void run() {
//		for(Integer id : subMap.keySet()) {
//			getPage(id, subMap.get(id));
//		}
	}
	static int lastId = 1413;
	static String lastListUrl = null;
	static boolean urlFlag = false;
	static long lastErrTime = 0l;
	public static void main(String[] args) {
		GrabDzdpImgsDataByProxy gdc = new  GrabDzdpImgsDataByProxy();
		gdc.getdata();
    }
	static Map<String, String> tags = new HashMap<String, String>();
	static {
		tags.put("photos/tag-%E7%8E%AF%E5%A2%83", "环境");
		tags.put("photos/tag-%E8%8F%9C", "菜");
		tags.put("photos/tag-%E4%BB%B7%E7%9B%AE%E8%A1%A8", "价目表");
		tags.put("photos/tag-%E5%85%B6%E4%BB%96", "其他");
		tags.put("officialphotos", "官方");
	}
	
	public void getdata() {
		List<ComShop> css= getShops();
		boolean flag = false;
		for(ComShop cs : css) {
			int id = cs.getId();
			if(lastId == 0 || id == lastId) {
				flag = true;
				continue;
			}
//			if(id == 298) break;
			try {
				if(flag) {
					int min = getmin(3, 15);
					System.out.print(cs.getOldId() + "==" + id + " , sleep=" + min+"=");
					Thread.sleep(min);
					for(String type : tags.keySet()) {
						getPage(cs, type, tags.get(type));
					}
					lastId = id;
				}
			} catch (Exception e) {
				long l = new Date().getTime();
				if(l - lastErrTime < 45000) break;
				lastErrTime = l;
				System.out.println(cs.getOldId() + "==id=" +e.getMessage());
				try {
					Thread.sleep(300000);
					getdata();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 获取头部导航菜单
	 * @param url
	 * @throws Exception 
	 * @throws FailingHttpStatusCodeException
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public void getPage(ComShop cs, String subUrl, String type) throws Exception {
		String url = baseUrl.replace("#id#", cs.getOldId()) +subUrl;
		Document doc = null;
		try {
			doc = GenericGrap.getDocumentByIp(url);
		} catch (HttpStatusException e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType(e.getStatusCode()+"");
			ge.setContent(JSON.toJSONString(cs));
			ge.setDescription("获取URL错误："+e.getMessage());
			insert2ErrDb(ge);
			if(e.getStatusCode() == 403 && e.getMessage().contains("HTTP error fetching URL")) throw e;
			return;
		} catch (Exception e) {
			// org.jsoup.HttpStatusException: HTTP error fetching URL. Status=404, URL=http://www.dianping.com/shop/66109152/photos/tag-%E5%85%B6%E4%BB%96
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("11");
			ge.setContent(JSON.toJSONString(cs));
			ge.setDescription("获取URL错误："+e.getMessage());
			insert2ErrDb(ge);
			if(e.getMessage().contains("HTTP error fetching URL")) throw e;
			return;
		}
		if(null == doc) return;
		List<String> pageUrls = new ArrayList<String>();
		pageUrls.add(url);
		// 获取分页 http://www.dianping.com/shop/18467095/review_more?pageno=35
		// 没有图片
		Elements pageels = doc.getElementsByAttributeValue("class", "aboutBox errorMessage");
		if(null != pageels && !pageels.isEmpty()) {
			System.out.print("=没有图片\n");
			return;
		}
		
		try {
			Elements aels = doc.getElementsByAttributeValue("class", "PageLink");
			if(null != aels && !aels.isEmpty()) {
				int pn = Integer.valueOf(aels.get(aels.size() - 1).text());
				for(int i = 2; i< pn+1; i++) {
					pageUrls.add(url + "?pg=" + i);
				}
			}

			System.out.print(type + "=图片列表页：" + pageUrls.size() + "页");
			for(String pageUrl : pageUrls) {
				if(!urlFlag && (null == lastListUrl || pageUrl.equals(lastListUrl))) {
					urlFlag = true;
					System.out.print("\n");
					if(null != lastListUrl) continue;
				}
				if(urlFlag) {
					int i = getmin(4, 20);
					System.out.print("=" + i + "毫秒 ");
					Thread.sleep(i);
					getList(pageUrl, cs, type);
					lastListUrl = pageUrl;
				}
			}
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("12");
			ge.setContent(cs.getId()+"");
			ge.setDescription("获取page 错误："+e.getMessage());
			insert2ErrDb(ge);
			if(e.getMessage().contains("HTTP error fetching URL")) throw e;
		}
	}
	
	private int getmin(int min, int max) {
		Random r = new Random();
		// 随机3~5秒访问看看
		int i = r.nextInt(max);
		if(i >= min && i<=max) {
			return i * 1000;
		} else {
			return getmin(min, max);
		}
	}

	public void getList(String url, ComShop cs, String type) throws Exception {
		Document doc = null;
		try {
			doc = GenericGrap.getDocumentByIp(url);
		} catch(Exception e) {
			GrapErr ge = new  GrapErr();
			ge.setUrl(url);
			ge.setType("13");
			ge.setContent(JSON.toJSONString(cs));
			ge.setDescription("获取List 错误："+e.getMessage());
			insert2ErrDb(ge);
			if(e.getMessage().contains("HTTP error fetching URL")) throw e;
			return;
		}
		List<ComShopImgs> csis = new ArrayList<ComShopImgs>();
		Elements els = doc.getElementsByAttributeValue("class", "J_list");
		if(null != els && !els.isEmpty()) {
			for(Element el : els) {
				ComShopImgs csi = new ComShopImgs();
				csi.setTypeName(type);
				csi.setShopId(cs.getId());
				csi.setShopName(cs.getFullName());
				
				Elements tempEls = el.getElementsByTag("img");
				if(null != tempEls && !tempEls.isEmpty()) {
					csi.setImgUrl(tempEls.first().attr("src"));
				}
				tempEls = el.getElementsByAttributeValue("class", "name");
				if(null != tempEls && !tempEls.isEmpty()) {
					tempEls = tempEls.first().getElementsByTag("a");
					if(null != tempEls && !tempEls.isEmpty()) {
						csi.setTitle(tempEls.first().text());
					}
				}
				csis.add(csi);
			}
		}

		System.out.println("，图片数=" + csis.size());
		insert2CscDb(csis);
	}

	
	public void insert2CscDb(List<ComShopImgs> csis) {
		String sql = "insert into com_shop_imgs(img_url,category_name,title,shop_name,type_name,shop_id) values(?,?,?,?,?,?)";
		PreparedStatement ps = null;
		try {
			ps = DbUtil.getComConn().prepareStatement(sql);
			for(ComShopImgs cc : csis) {
				ps.setString(1, cc.getImgUrl());
				ps.setString(2, cc.getCategoryName());
				ps.setString(3, getUtf8Str(cc.getTitle()));
				ps.setString(4, getUtf8Str(cc.getShopName()));
				ps.setString(5, getUtf8Str(cc.getTypeName()));
				ps.setInt(6, cc.getShopId());
				
				ps.addBatch();
			}	
			ps.executeBatch();	
		} catch (Exception e) {
			e.printStackTrace();
			GrapErr ge = new  GrapErr();
			ge.setType("15");
			ge.setContent(JSON.toJSONString(csis));
			ge.setDescription("插入Detail错误："+e.getMessage());
			insert2ErrDb(ge);
			return;
		} finally {
			if(null != ps) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private String getUtf8Str(String str) {
		try {
			str = null == str ? null : new String(str.getBytes(), "utf-8");//.replaceAll("[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]", "");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}

	public void insert2ErrDb(GrapErr ge) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("insert into grap_err(description,url,content,type) values(?,?,?,?)");
			grapPs.setString(1, ge.getDescription());
			grapPs.setString(2, ge.getUrl());
			grapPs.setString(3, ge.getContent());
			grapPs.setString(4, ge.getType());
			grapPs.execute();
			grapPs.close();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public static List<GrapErr> getErrs() {
		List<GrapErr> univs = new ArrayList<GrapErr>();
		try {
			Connection connection = DbUtil.getComConn();
			Statement statement = connection.createStatement();
			String sql = "select * from grap_err";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				GrapErr univ = new GrapErr();
				univ.setId(rs.getInt("id"));
				univ.setUrl(rs.getString("url"));
				univ.setType(rs.getString("type"));
				univ.setContent(rs.getString("content"));
				univs.add(univ);
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return univs;
	}
	
	public static void delErr(int id) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("delete from grap_err where id=?");
			grapPs.setInt(1, id);
			grapPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}
	
	public static void delMenu(int id) {
		PreparedStatement grapPs = null;
		try {
			grapPs = DbUtil.getComConn().prepareStatement("delete from com_menu where shop_id=?");
			grapPs.setInt(1, id);
			grapPs.execute();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			if(null != grapPs) {
				try {
					grapPs.close();
				} catch (SQLException e) {
					
				}
			}
		}
	}

	public static List<ComShop> getShops() {
		List<ComShop> css = new ArrayList<ComShop>();
		try {
			Connection connection = DbUtil.getComConn();
			Statement statement = connection.createStatement();
			String sql = "select  id,old_id,full_name from com_shop order by id asc";
			ResultSet rs = statement.executeQuery(sql);
			while(rs.next()) {
				ComShop cs = new ComShop();
				cs.setId(rs.getInt("id"));
				cs.setOldId(rs.getString("old_id"));
				cs.setFullName(rs.getString("full_name"));
				css.add(cs);
			}
			rs.close();
			statement.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return css;
	}
}
